package com.geline.mybatisplus.service;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.geline.mybatisplus.annotation.ExtractAfter;
import com.geline.mybatisplus.context.ExtractTableHelper;
import com.geline.mybatisplus.handler.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanMap;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @author mx
 * @date 2025/9/26
 */
@Slf4j
public class EasyExtractHandler {
    private ExtractTableHandler extractTableHandler;
    private ExtractStatusHandler extractStatusHandler;
    private ExtractStatus3Handler extractStatus3Handler;
    private ExtractValueHandler extractValueHandler;

    public EasyExtractHandler(ExtractTableHandler extractTableHandler, ExtractStatusHandler extractStatusHandler,
                              ExtractStatus3Handler extractStatus3Handler, ExtractValueHandler extractValueHandler) {
        this.extractTableHandler = extractTableHandler;
        this.extractStatusHandler = extractStatusHandler;
        this.extractStatus3Handler = extractStatus3Handler;
        this.extractValueHandler = extractValueHandler;
    }

    //自动回填属性
    public void handleExtractTable(Object entity, String sourceTable) {
        Object newEntity = fillExtractKey(entity, sourceTable);
        if(newEntity!=null){
            TableName annotation = entity.getClass().getAnnotation(TableName.class);
            String foreignKey = ExtractTableHelper.getForeignKey(annotation.value(), sourceTable);
            //更新主表状态字段（待处理，部分处理，已处理）
            extractStatusHandler.handle(newEntity);
            //更新主表状态字段（待处理，部分处理，已处理）
            extractStatus3Handler.handle(newEntity, sourceTable, foreignKey);
            //给满足条件的字段设置默认值
            extractValueHandler.handle(newEntity);
            //更新对象
            Db.updateById(newEntity);
            log.debug("updateById newEntity={}", JSONUtil.toJsonStr(newEntity));
        }
    }

    public Object fillExtractKey(Object entity, String sourceTable) {
        if(entity==null){
            log.warn("entity is null, sourceTable={}", sourceTable);
            return null;
        }
        String parentIdName = "id";
        Field[] fields = entity.getClass().getDeclaredFields();
        for(Field field : fields){
            TableId tableId = field.getAnnotation(TableId.class);
            if(tableId!=null){
                parentIdName = field.getName();
            }
        }
        Serializable idValue = (Serializable) BeanMap.create(entity).get(parentIdName);
        //先查询旧对象；再更新对象，如果存在@ExtractTable会继续执行更新父对象
        Object newEntity = Db.getById(idValue, entity.getClass());

        //处理 @ExtractKey @ExtractCount @ExtractSum 属性值
        Map<String, Object> updateValue = extractTableHandler.handleEntity(newEntity, sourceTable);
        if(updateValue!=null && updateValue.size()>0){
            updateValue.put(parentIdName, idValue);
        }
        log.info(">>>> updateFieldValue[{}]={}", newEntity.getClass().getSimpleName(), updateValue);
        return newEntity;
    }

    public void fillExtractAfter(List<Object> entityList) {
        if(entityList==null || entityList.isEmpty()){
            log.warn("not find entity ={}", entityList);
            return;
        }
        Object entity = entityList.iterator().next();
        if(entity!=null){
            Class<?> entityClass = entity.getClass();
            ExtractAfter[] extractAfters = entityClass.getAnnotationsByType(ExtractAfter.class);
            if (extractAfters != null && extractAfters.length>0) {
                for(ExtractAfter extractAfter : extractAfters){
                    ExtractAfterHandler handler = SpringUtil.getBean(extractAfter.handler());
                    handler.doHandle(entityList);
                }
            }
        }
    }
}
